package com.example.gmallproduct.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.common.constant.ProductConstant;
import com.common.to.SkuReductionTo;
import com.common.to.SpuBoundsTo;
import com.common.to.es.SkuEsUpTo;

import com.common.to.es.SkuHasStockTo;
import com.common.utils.R;
import com.example.gmallproduct.VO.other.*;
import com.example.gmallproduct.dao.*;
import com.example.gmallproduct.entity.*;
import com.example.gmallproduct.feign.CouponFeignService;
import com.example.gmallproduct.feign.SearchFeignService;
import com.example.gmallproduct.feign.WareFeignService;
import com.example.gmallproduct.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.utils.PageUtils;
import com.common.utils.Query;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {


    @Autowired
    private SpuInfoDao spuInfoDao;
    @Autowired
    private SpuInfoDescDao spuInfoDescDao;
    @Autowired
    private SpuImagesDao spuImagesDao;
    @Autowired
    private SpuImagesService spuImagesService;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private ProductAttrValueDao productAttrValueDao;
    @Autowired
    private SkuImagesService skuImagesService;
    @Autowired
    private SkuInfoService skuInfoService;
    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private CouponFeignService couponFeignService;
    @Autowired
    private BrandDao brandDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private ProductAttrValueDao attrValueDao;
    @Autowired
    private AttrDao attrDao;
    @Autowired
    private AttrService attrService;
    @Autowired
    private WareFeignService wareFeign;
    @Autowired
    private SearchFeignService searchFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }


    @Override
    @Transactional
    public void saveProduct(SpuSaveVo spuInfoVo) {
        //1.保存spu基本信息:spu_info
        SpuInfoEntity spuInfo = saveSpuBaseInfo(spuInfoVo);
        Long spuId = spuInfo.getId();
        //2.保存spu的描述图片:spu_info_desc
        saveSpuDesc(spuInfoVo, spuInfo);
        //3.保存spu的图片集spu_images
        saveSpuImages(spuInfoVo, spuId);
        //4.保存spu的规格参数product_attr_value
        saveProductAttr(spuInfoVo, spuId);
        //6.保存当前spu对应的sku信息
        //6.1 sku的基本信息,sku_info
        //6.2 sku的图片信息:sku_images
        //6.3 sku的销售属性:sku_sale_attr_value
        //6.4 sku的满减信息
        saveSkuInfo(spuInfoVo, spuInfo);
        //5.保存积分信息gulimall_sms---->sms-->spu_bounds
        R r = saveSpuBounds(spuInfoVo, spuId);
        if (r.getCode() != 0) {
            log.error("远程调用保存积分信息失败");
        }
    }

    @Override
    public PageUtils queryListByKey(Map<String, Object> params) {
//        brandId: 0,
//                catelogId: 0
        String key = (String) params.get("key");
        Object brandId = params.get("brandId");
        Object catelogId = params.get("catelogId");

        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        if (brandId != null) {
            wrapper.eq("brand_id", Long.parseLong((String) brandId));
        }
        if (catelogId != null) {
            wrapper.eq("catalog_id", Long.parseLong((String) catelogId));
        }
        if (key != null && key.length() > 0) {
            wrapper.like("spu_name", key).or().like("spu_description", key);
        }

        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public void up(Long spuId) {
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.queryBySpuId(spuId);
        //1. 查询所有spu可以被检索的属性
        QueryWrapper<ProductAttrValueEntity> wrapper = new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId);
        //当前spu的所有属性
        List<ProductAttrValueEntity> attrValueEntities = attrValueDao.selectList(wrapper);
        // 1.1 检索可以被搜索的属性
        ArrayList<Long> ids = new ArrayList<>();
        attrValueEntities.forEach((attrVal) -> {
            if (attrVal.getAttrId() != null) {
                ids.add(attrVal.getAttrId());
            }
        });
        ArrayList<AttrEntity> attrCanSearchlist = new ArrayList<>();
        for (Long id : ids) {
            QueryWrapper<AttrEntity> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("search_type", 1);
            wrapper1.eq("attr_id", id);
            AttrEntity entity = attrDao.selectOne(wrapper1);
            if (entity != null) {
                attrCanSearchlist.add(entity);
            }
        }
        List<SkuEsUpTo.Attr> attrList = attrCanSearchlist.stream().map((attrEntity) -> {
            SkuEsUpTo.Attr attr = new SkuEsUpTo.Attr();
            attr.setAttrName(attrEntity.getAttrName());
            attr.setAttrId(attrEntity.getAttrId());

            QueryWrapper<ProductAttrValueEntity> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("spu_id", spuId).eq("attr_id", attrEntity.getAttrId());
            ProductAttrValueEntity valueEntity = productAttrValueDao.selectOne(wrapper1);
            attr.setAttrValue(valueEntity.getAttrValue());
            return attr;
        }).collect(Collectors.toList());
        //收集所有skuId
        List<Long> ids1 = skuInfoEntities.stream().map((sku) -> {
            return sku.getSkuId();
        }).collect(Collectors.toList());
        //远程调用获取库存量
        R<SkuHasStockTo> r = wareFeign.hasStock(ids1);
        // feign远程调用返回的泛型数据为空,甚至没有data字段(hashMap自定义属性无效)
//        List<SkuHasStockTo> listStock = r.getData();
        List<SkuHasStockTo> listStock = null;
        if (r.get("data") != null) {
            listStock = (List<SkuHasStockTo>) r.get("data");
        }
        //将list类型数据转换为map型
        assert listStock != null;
        Map<Long, Integer> stockMap = listStock.stream().collect(Collectors.toMap(SkuHasStockTo::getSkuId, SkuHasStockTo::getStock));
        //2. 从sku中拷贝基本属性
        List<SkuEsUpTo> skuEsUpToList = skuInfoEntities.stream().map((sku) -> {
            SkuEsUpTo esUpTo = new SkuEsUpTo();
            BeanUtils.copyProperties(sku, esUpTo);
            //skuprice,skuImage
            esUpTo.setSkuImg(sku.getSkuDefaultImg());
            esUpTo.setSkuPrice(sku.getPrice());
            //brandName,catalogName
            BrandEntity brandEntity = brandDao.selectById(sku.getBrandId());
            esUpTo.setBrandName(brandEntity.getName());
            CategoryEntity categoryEntity = categoryDao.selectById(sku.getCatalogId());
            esUpTo.setCatalogName(categoryEntity.getName());
            esUpTo.setAttrs(attrList);
            //热度系数默认都给1
            esUpTo.setHotScore(1L);
            //设置库存
            if (stockMap == null) {
                esUpTo.setHasStock(true);
            } else {
                if (stockMap.get(sku.getSkuId()) != null && stockMap.get(sku.getSkuId()) > 0) {
                    esUpTo.setHasStock(true);
                } else {
                    esUpTo.setHasStock(false);
                }
            }
            return esUpTo;
        }).collect(Collectors.toList());

        // 商品上架
        searchFeignService.up(skuEsUpToList);
        //  商品上架成功后需要修改数据库状态
//        spuInfoDao.updatePublishState(spuId, ProductConstant.PRODUCT_UP.getCode());
        UpdateWrapper<SpuInfoEntity> wrapper1 = new UpdateWrapper<>();
        wrapper1.eq("id", spuId);
        wrapper1.set("publish_status", ProductConstant.PRODUCT_UP.getCode());
        spuInfoDao.update(new SpuInfoEntity(), wrapper1);
        System.out.println("商品上架成功..................");
    }

    /**
     * 保存spu积分信息
     *
     * @param spuInfoVo spu的基本信息对象
     * @param spu_id    spu的id
     * @return 保存积分的远程调用响应
     */
    private R saveSpuBounds(SpuSaveVo spuInfoVo, Long spu_id) {
        Bounds bounds = spuInfoVo.getBounds();
        SpuBoundsTo spuBoundsTo = new SpuBoundsTo();
        spuBoundsTo.setBuyBounds(bounds.getBuyBounds());
        spuBoundsTo.setGrowBounds(bounds.getGrowBounds());
        spuBoundsTo.setSpuId(spu_id);
        return couponFeignService.saveSpuBounds(spuBoundsTo);
    }

    /**
     * 保存sku以及sku图片信息,销售属性信息
     */
    private void saveSkuInfo(SpuSaveVo spuInfoVo, SpuInfoEntity spuEntity) {
        List<Skus> skus = spuInfoVo.getSkus();
        if (skus != null && skus.size() > 0) {
            for (Skus sku : skus) {
                //保存sku基本信息
                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtils.copyProperties(sku, skuInfoEntity);
                //查找默认图片
                List<Images> images = sku.getImages();
                String defaultImage = "";
                if (images != null && images.size() > 0) {
                    for (Images image : images) {
                        if (image.getDefaultImg() == 1) {
                            defaultImage = image.getImgUrl();
                        }
                    }
                }
//                skuInfoEntity.setSkuDesc();
                skuInfoEntity.setSpuId(spuEntity.getId());
                skuInfoEntity.setBrandId(spuEntity.getBrandId());
                skuInfoEntity.setCatalogId(spuEntity.getCatalogId());
                skuInfoEntity.setSkuDefaultImg(defaultImage);
                skuInfoEntity.setSaleCount(0L);
                skuInfoService.save(skuInfoEntity);
                //保存sku图片信息
                List<SkuImagesEntity> collect = images.stream().map((image) -> {
                    SkuImagesEntity entity = new SkuImagesEntity();
                    entity.setDefaultImg(image.getDefaultImg());
                    entity.setSkuId(skuInfoEntity.getSkuId());
                    entity.setImgUrl(image.getImgUrl());
                    return entity;
                }).filter((entity) -> {
                    return !StringUtils.isEmpty(entity.getImgUrl());
                }).collect(Collectors.toList());
                skuImagesService.saveBatch(collect);
                //保存销售属性信息
                List<Attr> attr = sku.getAttr();
                List<SkuSaleAttrValueEntity> collect1 = attr.stream().map((attr1 -> {
                    SkuSaleAttrValueEntity saleAttr = new SkuSaleAttrValueEntity();
                    BeanUtils.copyProperties(attr1, saleAttr);
                    saleAttr.setSkuId(skuInfoEntity.getSkuId());
                    return saleAttr;
                })).collect(Collectors.toList());
                skuSaleAttrValueService.saveBatch(collect1);
                //保存sku的满减信息
                SkuReductionTo skuReductionTo = new SkuReductionTo();
                skuReductionTo.setSkuId(skuInfoEntity.getSkuId());
                BeanUtils.copyProperties(sku, skuReductionTo);

                if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal(0)) == 1) {
                    R r = couponFeignService.saveSkuReductionInfo(skuReductionTo);
                    if (r.getCode() != 0) {
                        log.error("远程调用保存满减信息失败");
                    }
                }
            }
        }
    }

    /**
     * 保存规格参数(baseAttr)
     */
    private List<ProductAttrValueEntity> saveProductAttr(SpuSaveVo spuInfoVo, Long spu_id) {
        List<BaseAttrs> baseAttrs = spuInfoVo.getBaseAttrs();
        if (baseAttrs != null && baseAttrs.size() > 0) {
            List<ProductAttrValueEntity> collect = baseAttrs.stream().map((baseAttr) -> {
                ProductAttrValueEntity entity = new ProductAttrValueEntity();
                entity.setAttrId(baseAttr.getAttrId());
                entity.setSpuId(spu_id);
                entity.setQuickShow(baseAttr.getShowDesc());
                entity.setAttrValue(baseAttr.getAttrValues());
                return entity;
            }).collect(Collectors.toList());
            productAttrValueService.saveBatch(collect);
            return collect;
        }
        return null;
    }

    /**
     * 保存spu的图片集,
     */
    private List<SpuImagesEntity> saveSpuImages(SpuSaveVo spuInfoVo, Long spu_id) {

        List<String> images = spuInfoVo.getImages();
        if (images != null && images.size() > 0) {
            //目前只保存spu_id和image_url
            List<SpuImagesEntity> list = images.stream().map((url) -> {
                SpuImagesEntity entity = new SpuImagesEntity();
                entity.setSpuId(spu_id);
                entity.setImgUrl(url);
                return entity;
            }).collect(Collectors.toList());
            spuImagesService.saveBatch(list);
            return list;
        }
        return null;
    }

    /**
     * 保存spu的描述图片信息
     *
     * @param spuInfoVo  用于获取描述图片信息
     * @param infoEntity 用于获取spu_id
     */
    private SpuInfoDescEntity saveSpuDesc(SpuSaveVo spuInfoVo, SpuInfoEntity infoEntity) {
        List<String> decript = spuInfoVo.getDecript();
        if (decript != null && decript.size() > 0) {
            String joinDesc = String.join(",", decript);
            SpuInfoDescEntity descEntity = new SpuInfoDescEntity();
            descEntity.setSpuId(infoEntity.getId());
            descEntity.setDecript(joinDesc);
            //保存
            spuInfoDescDao.insert(descEntity);
            return descEntity;
        }
        return null;
    }

    /**
     * 保存spu基本信息
     */
    private SpuInfoEntity saveSpuBaseInfo(SpuSaveVo spuInfoVo) {
        SpuInfoEntity infoEntity = new SpuInfoEntity();
        infoEntity.setCreateTime(new Date());
        infoEntity.setUpdateTime(new Date());
        BeanUtils.copyProperties(spuInfoVo, infoEntity);
        this.baseMapper.insert(infoEntity);
        return infoEntity;
    }


}